﻿using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;


/// <summary>
/// MapHandler 的摘要说明
/// </summary>
public class MapHandler
{
    /*
        select AsSVG(intersection(Simplify(the_geom,2),
geometryfromtext(
 'POLYGON((-113.8 48.8,-113.0 48.8,-113.0 35.2,-113.8 35.2,-113.8 48.8))'))) from cities 
 where the_geom && setsrid('BOX3D(-113.8 48.8,-113.0 35.2)'::box3d,-1)
         * */

    //获取全图
    public string GetFullExtentMapData(string layerName,string propertyField,string geometryField,GeometryType geometryType)
    {
        
        string sSql = string.Format("select {0}, assvg({1}) as geom from {2}",propertyField,geometryField,layerName);
        string sSVGData = "";

        BoundBox oBBox = this.GetLayerBBox(layerName, geometryField);

        DatabaseOper oDatabaseOper = new DatabaseOper();
        DataTable dtLayer = oDatabaseOper.GetDataFromDatabase(sSql);

        //sSVGData += "<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:attrib='http://www.carto.net/attrib'";
        //sSVGData += string.Format(" width='100%' height='100%'  viewBox='{0} {1} {2} {3}'>", oBBox.MinX, oBBox.MinY,oBBox.Width,oBBox.Height);

        sSVGData += this.ParseRowToSVG(dtLayer, layerName,propertyField, "geom", geometryType);

        //sSVGData += "</svg>";

        return sSVGData;
    }

    //获取指定区域的地图数据
    public string GetSingleLayerData(double minX,double minY,double maxX,double maxY,string layerName,string propertyField,string geometryField,GeometryType geoType)
    {
        double dWidth = 0;
        double dHeight = 0;
        double dSimplifyTolerance = 0;
        string sSql = "";

        dWidth = Math.Abs(maxX - minX);
        dHeight = Math.Abs(maxY - minY);

        dSimplifyTolerance = dWidth / 800;

        sSql = string.Format("select {0}, AsSVG(intersection({1},"
            + "geometryfromtext('POLYGON(({2} {3},{4} {3},{4} {5},{2} {5},{2} {3}))'))) as geom from {6}"
            + " where the_geom && setsrid('BOX3D({2} {3},{4} {5})'::box3d,-1)", propertyField,geometryField,minX, minY, maxX, maxY, layerName);

        DatabaseOper oDatabaseOper = new DatabaseOper();
        DataTable dtLayer = oDatabaseOper.GetDataFromDatabase(sSql);

        return this.ParseRowToSVG(dtLayer, layerName, propertyField, "geom", geoType);
    }

    public string GetSVGMapData(double minX, double minY, double maxX, double maxY,MapLevelInfomation mapLevelInfo)
    {
        string sSVGData = string.Empty;

        //sSVGData += "<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:attrib='http://www.carto.net/attrib'";
       // sSVGData += string.Format(" width='100%' height='100%'  viewBox='{0},{1},{2},{3}'>", minX, minY, Math.Abs(maxX - minX), Math.Abs(maxY - minY));
        sSVGData += "<g id='mapData'>";

        foreach (LayerInformation oLayerInfo in mapLevelInfo.LayerInfomations)
        {
            sSVGData += this.GetSingleLayerData(minX, minY, maxX, maxY, oLayerInfo.LayerName, oLayerInfo.PropertyField, oLayerInfo.GeomField, oLayerInfo.GeomType);
        }

        //sSVGData += "</svg>";
        sSVGData += "</g>";

        return sSVGData;
    }

    private string ParseRowToSVG(DataTable geoDataTable, string layerName,string propertyField,string geoFieldName,GeometryType geoType)
    {
        string sRing = "";
        string sLayerString = "";
        string sCoords = "";
        string sProperty = "";

        sLayerString += "<g id='" + layerName + "' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:attrib='http://www.carto.net/attrib' fill='green' fill-opacity='0.5' stroke='blue' stroke-width='0.02'>";

        if (geoType == GeometryType.Polygon)
            sRing = "z";

        foreach (DataRow dr in geoDataTable.Rows)
        {
            sCoords = dr[geoFieldName].ToString();
            sProperty = dr[propertyField].ToString();

            if (geoType == GeometryType.Polygon || geoType == GeometryType.PolyLine)
                sLayerString += "<path attrib:name='" + sProperty + "' d='" + sCoords + sRing + "'/>";
            else if (geoType == GeometryType.Point)
                sLayerString += "<circle attrib:name='" + sProperty + "' r='4' " + sCoords + " />"; 
        }

        sLayerString += "</g>";

        return sLayerString;
    }

    public BoundBox GetLayerBBox(string layerName, string geometryFiled)
    {
        string sSql = string.Format("select ST_extent({0}) from {1}", geometryFiled, layerName);
        DatabaseOper oDatabaseOper = new DatabaseOper();

        string sBBox = oDatabaseOper.GetStatisticValueFromDatabase(sSql).ToString().ToLower();

        sBBox = sBBox.Replace("box(", "");
        sBBox = sBBox.Replace(")", "");

        BoundBox oBound = new BoundBox();
        string[] sBBoxPars = sBBox.Split(',');
        string[] sTopLeftCoord = sBBoxPars[0].Split(' ');
        string[] sBottonRightCoord = sBBoxPars[1].Split(' ');

        oBound.MinX = double.Parse(sTopLeftCoord[0]);
        oBound.MinY = double.Parse(sBottonRightCoord[1]) * -1;
        oBound.Width = Math.Abs(double.Parse(sBottonRightCoord[0]) - double.Parse(sTopLeftCoord[0]));
        oBound.Height = Math.Abs(double.Parse(sBottonRightCoord[1]) - double.Parse(sTopLeftCoord[1]));
        
        return oBound;
    }

    
}
